<?php
/**
 * 支付宝支付
 * User: shenyvlin
 * Date: 2019/3/2
 * Time: 16:13
 */
namespace app\avikcm\controller;

use think\facade\Config;
use think\facade\Request;
use app\api\model\Paymodel;
require '../extend/alipay/aop/AopClient.php';
require '../extend/alipay/aop/request/AlipayTradeAppPayRequest.php';
require '../extend/alipay/aop/request/AlipayTradeRefundRequest.php';
class Alipay{
    protected $aop;
    /**
     * 初始化
     */
    public function __construct()
    {
        $this->aop    =    new \AopClient();
        $this->aop->appId                  = Config::get('app.alipay.appId');
        $this->aop->gatewayUrl             = Config::get('app.alipay.gatewayUrl');
        $this->aop->rsaPrivateKey          = Config::get('app.alipay.rsaPrivateKey');//私有密钥（步骤二中生成的商户私有秘钥）
        $this->aop->alipayrsaPublicKey     = Config::get('app.alipay.alipayrsaPublicKey');//商户公钥（步骤二中生成的商户公钥）
        $this->aop->alipayPublicKey        = Config::get('app.alipay.alipayPublicKey');//支付宝公钥
        $this->aop->format                 = Config::get('app.alipay.format');
        $this->aop->charset                = Config::get('app.alipay.charset');
        $this->aop->signType               = Config::get('app.alipay.signType');
    }

    /**
     * 创建APP支付订单 - 请求支付宝
     *
     * @param string $order_sn 商户网站唯一订单号
     * @param string $body 对一笔交易的具体描述信息。
     * @param string $subject 商品的标题/交易标题/订单标题/订单关键字等。
     * @param string $total_amount 订单金额
     * @return array 返回订单信息
     */
    public function createAppPay($order_sn,$body, $subject, $total_amount)
    {
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        $request = new \AlipayTradeAppPayRequest();

        //SDK已经封装掉了公共参数，这里只需要传入业务参数
        $bizcontent    =    [
            'body'                =>    $body,
            'subject'             =>    $subject,
            'out_trade_no'        =>    $order_sn,
            'timeout_express'     =>    '30m',//失效时间
            'total_amount'        =>    $total_amount,//价格
            'product_code'        =>    'QUICK_MSECURITY_PAY',
            'goods_type'          =>    1,
        ];

        //商户外网可以访问的异步地址 (异步回掉地址，根据自己需求写)
        $request->setNotifyUrl("http://".$_SERVER['HTTP_HOST']."/api/pay/payment/aliNotify");
        $request->setBizContent(json_encode($bizcontent, JSON_UNESCAPED_UNICODE));

        //这里和普通的接口调用不同，使用的是sdkExecute
        $response = $this->aop->sdkExecute($request);

        return $response;
    }

    /**
     * 支付宝支付异步回调
     */
    public function payCallback(){
        $request    = Request::post();
        $verify = $this->aop->rsaCheckV1($request,null,'RSA2');
        if ($verify) { // 验证成功
            if ($request['trade_status'] == 'TRADE_FINISHED' || $request['trade_status'] == 'TRADE_SUCCESS') {
                return $request;
            }
        } else {
            // 验证失败
            return false;
        }
    }

    /**
     * 支付宝退款
     *
     * @param string $out_trade_no 商户网站唯一订单号
     * @param string $out_trade_no 支付宝交易号
     * @param string $refund_amount 退款金额
     * @param string $refund_reason 退款原因
     * @return array 返回订单信息
     */
    public function refund($out_trade_no, $trade_no, $refund_amount, $refund_reason)
    {
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        $request = new \AlipayTradeRefundRequest();

        //SDK已经封装掉了公共参数，这里只需要传入业务参数
        $bizcontent    =    [
            'out_trade_no'        =>    $out_trade_no,
            'trade_no'            =>    $trade_no,
            'refund_amount'       =>    $refund_amount,
            'refund_reason'       =>    $refund_reason,
            'timeout_express'     =>    '30m',//失效时间
            'product_code'        =>    'QUICK_MSECURITY_PAY',
            'goods_type'          =>    1,
        ];

        //商户外网可以访问的异步地址 (异步回掉地址，根据自己需求写)
        // $request->setNotifyUrl("http://".$_SERVER['HTTP_HOST']."/api/pay/payment/aliRefund");
        $request->setBizContent(json_encode($bizcontent, JSON_UNESCAPED_UNICODE));

        //这里和普通的接口调用不同，使用的是sdkExecute
        $response = $this->aop->sdkExecute($request);

        return $response;
    }
}